﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Castle.Core;
using Castle.Core.Logging;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using MusicStore.Silverlight.Views;
using MusicStore.Silverlight.ViewModels;
using MusicStore.Silverlight.Infrastructure;
using MusicStore.Silverlight.Helpers;
using System.Windows.Navigation;
using System.Threading;
using Castle.Core.Interceptor;
using Structura.Silverlight.Infrastructure.Logging;
using Structura.Silverlight.Infrastructure.Navigation;
using Structura.Silverlight.Infrastructure.ViewModel;
using MusicStore.Silverlight.Commands;

namespace MusicStore.Silverlight
{
    public partial class App : Application
    {
        // public static WindsorContainer Container { get; private set; }

        private IServiceLocator ServiceLocator;

        private void Bootstrap()
        {
            WindsorContainer Container = new WindsorContainer();

            Container.Kernel.AddFacility("ViewModelInitializationFacility", new ViewModelInitializationFacility());

            // Container.AddFacility<LoggingFacility>();

            Container.Kernel.AddFacility("LoggingFacility",
                                         new LoggingFacility(new LoggerConfig() { Level = LoggerLevel.Debug, AppendersNames = new[] { "DefAppender" } }));
            Container.Register(
                Component.For<IAppender>().ImplementedBy<BrowserConsoleAppender>().Named("DefAppender"),
                Component.For<IInterceptor>().ImplementedBy<LoggerInterceptor>().Named("LoggerInterceptor")
                );

            //Logger log = new Logger(LoggerLevel.Debug, new List<IAppender> {new BrowserConsoleAppender()});
            //Container.Register(
            //   Component.For<ILogger>().Instance(log));

            //Container.Register(
            //   Component.For<IAppender>().ImplementedBy<BrowserConsoleAppender>().Named("DefAppender"),
            //   Component.For<IAppender>().ImplementedBy<BrowserConsoleAppender>().Named("DefAppender2"),
            //   Component.For<ILogger>().ImplementedBy<Logger>()
            //      .DynamicParameters((k, d) =>
            //                           {
            //                              d["loggerLevel"] = LoggerLevel.Debug;
            //                              d["appenders"] = k.ResolveAll<IAppender>();
            //                           }));

            // Features registration

            Container.Register(
                // application infrastructure and shell configuration
                Component.For<IPageProvider>().ImplementedBy<PageProvider>(),
                Component.For<INavigationContentLoader>().ImplementedBy<IocNavigationContentLoader>(),
                Component.For<MainPage>(), //.Interceptors(InterceptorReference.ForKey("LoggerInterceptor")).Last

                // search Feature
                Component.For<SearchCommand>(), //.Interceptors(InterceptorReference.ForKey("LoggerInterceptor")).Last,
                Component.For<NavigateToAlbumCommand>(), //.Interceptors(InterceptorReference.ForKey("LoggerInterceptor")).Last,
                Component.For<ISearchViewModel>().ImplementedBy<SearchViewModel>().LifeStyle.Custom<Structura.Castle.Windsor.Lifecycle.SingletonLifestyleManager>(), //.Interceptors(InterceptorReference.ForKey("LoggerInterceptor")).Last,
                Component.For<ISearchView>().ImplementedBy<Search>().Named("Search"),

                // album management feature
                Component.For<IAlbumViewModel>().ImplementedBy<AlbumViewModel>().Interceptors(InterceptorReference.ForKey("LoggerInterceptor")).Last,
                Component.For<IAlbumView>().ImplementedBy<Album>().Named("Album")
                );

            ServiceLocator = new CastleWindsorServiceLocator(Container);
        }

        public App()
        {
            this.Startup += this.Application_Startup;
            this.UnhandledException += this.Application_UnhandledException;

            InitializeComponent();
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // configure the static container
            Bootstrap();

            // set the dispatcher
            MainPage p = ServiceLocator.Resolve<MainPage>();
            UiDispatcher.SetDispatcher(new WindowsDispatcher(p.Dispatcher));

            this.RootVisual = p;

            ILogger logger = ServiceLocator.Resolve<ILogger>();
            logger.Info("Application Started");
        }

        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            ServiceLocator.Resolve<ILogger>().Error("Unhandled Error in Silverlight Application", e.ExceptionObject);

            // If the app is running outside of the debugger then report the exception using
            // a ChildWindow control.
            if (!System.Diagnostics.Debugger.IsAttached)
            {
                // NOTE: This will allow the application to continue running after an exception has been thrown
                // but not handled. 
                // For production applications this error handling should be replaced with something that will 
                // report the error to the website and stop the application.
                e.Handled = true;
                ChildWindow errorWin = new ErrorWindow(e.ExceptionObject);
                errorWin.Show();
            }
        }
    }
}